using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;

public class NetMgr : MonoBehaviour
{
    private static NetMgr instance;
    private static readonly object lockObject = new object();
    public static NetMgr Instance
    {
        get
        {
            // 双重检查锁定实现线程安全
            if (instance == null)
            {
                lock (lockObject)
                {
                    if (instance == null)
                    {
                        GameObject go = new GameObject("NetMgr");
                        instance = go.AddComponent<NetMgr>();
                        DontDestroyOnLoad(go); // 场景切换时保持单例
                    }
                }
            }
            return instance;
        }
    }
    // 客户端
    private Socket socket;
    //用于发送消息的队列 公共容器 主线程往里面放 发送线程往里面取
    private Queue<string> sendQueue = new Queue<string>();
    //用于接收消息的队列 公共容器 接收线程往里面放 主线程往里面取   
    private Queue<string>  recvQueue = new Queue<string>();
    //接受消息的线程
    private Thread sendThread;
    //发送消息的线程
    private Thread recvThread;
    //用于收消息的容器
    private byte[] recvBuffer = new byte[1024 * 1024];
    //返回收到的字节数
    private int recvLen;

    private bool isConnect = false;
    void Awake()
    {
        // 确保只有一个实例存在
        if (instance != null && instance != this)
        {
            Destroy(gameObject);
        }
        else
        {
            instance = this;
            DontDestroyOnLoad(gameObject);
        }
    }
    void Update()
    {
        if (recvQueue.Count > 0)
        {
            print("收到数据：" +recvQueue.Dequeue());
        }
    } 

    public void Connect(string ip, int port)
    {
        if (socket == null)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        }
        //连接服务端
        IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ip), port);
        try
        {
            socket.Connect(ipPoint);
            print("连接成功");
            this.isConnect = true;
            //开启发送线程
            sendThread = new Thread(SendMsg);
            sendThread.Start();
            //开启接受线程
            recvThread = new Thread(ReceiveMsg);
            recvThread.Start();
        }   
        catch (SocketException e)
        {
            if (e.ErrorCode == 10061)
            {
                print("服务器拒绝连接");
            }
            else
            {
                print("连接服务器失败" + e.ErrorCode + e.Message);
            }
        }
    }

    public void Send(string data)
    {
        // //简单的发送消息
        // if(this.socket != null)
        // {
        //     socket.Send(Encoding.UTF8.GetBytes(data));
        // }
        sendQueue.Enqueue(data);
    }

    public void Close()
    {
        if(this.socket != null)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
                     this.isConnect = true;
        }
    }

    private void SendMsg(object obj)
    {
        while (isConnect)
        {
            if (sendQueue.Count > 0)
            {
                socket.Send(Encoding.UTF8.GetBytes(sendQueue.Dequeue()));
            }
        }
    }
    //不停的接受消息
    private void ReceiveMsg(object obj)
    {
        while (isConnect)
        {
            if (socket.Available > 0)
            {
                this.recvLen = socket.Receive(this.recvBuffer);
                //收到消息 并 解析消息为字符串 放入公共容器             
                recvQueue.Enqueue(Encoding.UTF8.GetString(this.recvBuffer, 0, this.recvLen));
            }
        }
    }

    void OnDestroy()
    {
        Close(); 
    }
}